﻿using LitJson;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace PackageBuilder
{
    public partial class Form1 : Form
    {
        List<string> filePathList = new List<string>();
        byte[] header;

        public Form1()
        {
            InitializeComponent();

            button1.Click += Button1_Click;

            button2.Click += Button2_Click;

            button3.Click += Button3_Click;

            button4.Click += Button4_Click;

            openFileDialog1.RestoreDirectory = true;
            saveFileDialog1.RestoreDirectory = true;

            BindingSource bs = new BindingSource();
            bs.DataSource = filePathList;
            listBox1.DataSource = bs;

            listBox1.MouseDown += (o, e) =>
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (listBox1.SelectedItems.Count > 0)
                        contextMenuStrip1.Show(listBox1, e.Location);
                }
            };

            DeleteToolStripMenuItem.Click += (o, e) =>
            {
                if (listBox1.SelectedItems.Count > 0)
                {
                    foreach (string item in listBox1.SelectedItems)
                    {
                        filePathList.Remove(item);
                    }
                    ((BindingSource)listBox1.DataSource).ResetBindings(true);
                }
            };
        }

        private void Button1_Click(object sender, EventArgs e)
        {
            OpenFiles();
        }

        private void OpenFiles()
        {
            openFileDialog1.Multiselect = true;
            var result = openFileDialog1.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                filePathList.AddRange(openFileDialog1.FileNames);
                ((BindingSource)listBox1.DataSource).ResetBindings(true);
            }
        }

        private void Button2_Click(object sender, EventArgs e)
        {
            SavePkg();
        }

        private async void SavePkg()
        {
            saveFileDialog1.Filter = "tvrs|*.tvrs";
            var result = saveFileDialog1.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                if (filePathList.Count > 0)
                {
                    var fileinfoList = new List<Fileinfo>();

                    filePathList.ForEach(o =>
                    {
                        FileInfo f = new FileInfo(o);
                        fileinfoList.Add(new Fileinfo(f.Name, f.Length));
                    });

                    string strHeader = JsonMapper.ToJson(fileinfoList);

                    byte[] tmpByte = Encoding.UTF8.GetBytes(strHeader);

                    header = new byte[tmpByte.Length];

                    for (int i = 0; i < tmpByte.Length; i++)
                    {
                        header[i] = tmpByte[i];
                    }

                    byte[] headerLength = BitConverter.GetBytes(header.Length);

                    if (File.Exists(saveFileDialog1.FileName))
                    {
                        File.Delete(saveFileDialog1.FileName);

                        await Task.Delay(100);
                    }

                    FileStream pkgStream = File.OpenWrite(saveFileDialog1.FileName);

                    pkgStream.Write(headerLength, 0, headerLength.Length);

                    pkgStream.Write(header, 0, header.Length);

                    filePathList.ForEach(o =>
                   {
                       var buffer = ReadFile(o);

                       pkgStream.WriteAsync(buffer, 0, buffer.Length);
                   });

                    await Task.Delay(10);

                    pkgStream.Close();
                }
            }
        }

        private byte[] ReadFile(string path)
        {
            FileStream fs = File.OpenRead(path);

            byte[] buffer = new byte[fs.Length];

            fs.Read(buffer, 0, buffer.Length);

            fs.Close();

            return buffer;
        }

        private void Button3_Click(object sender, EventArgs e)
        {
            ReleaseResources();
        }

        private void ReleaseResources()
        {
            openFileDialog1.Multiselect = false;
            var result = openFileDialog1.ShowDialog(this);
            if (result == DialogResult.OK)
            {
                using (FileStream fs = File.OpenRead(openFileDialog1.FileName))
                {
                    byte[] headerLength = new byte[4];
                    fs.Read(headerLength, 0, headerLength.Length);
                    int length = BitConverter.ToInt32(headerLength, 0);

                    byte[] headerBuffer = new byte[length];
                    fs.Read(headerBuffer, 0, headerBuffer.Length);

                    result = folderBrowserDialog1.ShowDialog(this);
                    if (result == DialogResult.OK)
                    {
                        var jsonData = JsonMapper.ToObject(Encoding.UTF8.GetString(headerBuffer));

                        List<Fileinfo> fileinfoList = new List<Fileinfo>();

                        foreach (JsonData item in jsonData)
                        {
                            fileinfoList.Add(new Fileinfo(item["FileName"].ToString(), long.Parse((item["FileSize"].ToString()))));
                        }

                        Dictionary<string, Image> skinRes = new Dictionary<string, Image>();

                        MemoryStream ms = null;

                        fileinfoList.ForEach(o =>
                        {
                            //if (ms != null)
                            //{
                            //    ms.Close();
                            //    ms.Dispose();
                            //}

                            byte[] imgBuffer = new byte[o.FileSize];
                            fs.Read(imgBuffer, 0, (int)o.FileSize);

                            //ms = new MemoryStream(imgBuffer);

                            //skinRes[o.FileName] = Image.FromStream(ms);


                            string filePath = Path.Combine(folderBrowserDialog1.SelectedPath, o.FileName);
                            if (File.Exists(filePath))
                                File.Move(filePath, filePath + ".bak");

                            File.WriteAllBytes(filePath, imgBuffer);
                        });

                        //fs.Position = 0;
                        fs.Close();
                        fs.Dispose();

                        //Image img = skinRes.FirstOrDefault().Value;

                        //panel1.BackgroundImage = img;
                        //panel2.BackgroundImage = img;
                    }
                }
            }
        }

        private void Button4_Click(object sender, EventArgs e)
        {
            filePathList.Clear();
            ((BindingSource)listBox1.DataSource).ResetBindings(true);
        }
    }

    class Fileinfo
    {
        public string FileName;
        public long FileSize;

        public Fileinfo(string name, long size)
        {
            FileName = name;
            FileSize = size;
        }
    }
}
